/***************************************************************************
 *   Copyright (C) 2002-2011 by Ferdowsi University of Mashhad,            *
 *   Software Simulation and Modeling lab                                  *
 *   nexus@um.ac.ir                                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef TRAINER_H
#define TRAINER_H

#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <time.h>
//#include <pthread.h>
#include "../../Utilidade/include/Lado.h"
#include "../../Matematica/include/Matriz4d.h"
#include "../../Matematica/include/Coordenada3d.h"
#include "../../Conexao/include/ConexaoTCP.h"

#include "../../Agente/include/Agente.h"

#include "../../Estatisticas/include/estatistica.h"

#include "ParserTrainer.h"

class Trainer{
public:
	Trainer();
    Trainer(std::string host, std::string port);
    Trainer(std::string log);
    ~Trainer(){}

    /*MÉTODOS PARA ALTERAÇÃO DE CENARIO*/
    void moveBall(Coordenada3d);
    void moveGround(Coordenada3d,Coordenada3d);
    void moveAgent(int unum,Lado,Coordenada3d,Coordenada3d,double,double);
    void setPlayMode(std::string);

    /*MÉTODOS DE COMUNICAÇÃO COM O SERVIDOR*/
    void send(std::string);
    void receive();
    void update(std::string msg);

    /*=================  Métodos novos  ===============================================================*/

    void mensagemParseTreiner(std::string);/*Metodo que recebe cada expressaoo e chama atualizacaoAgentes*/
    void atualizacaoAgentes(std::string ,int ,double );
    void atualizarPosicoes(std::string ,int ,double );
    void setaPosicaoPartes(std::string);
    void listaDadosAgentes();
    int posseDeBola(int);
    void leitorArquivo();
    void abrirArquiGravacaoCoordenadas();
    void setListaDadosJogo(std::string);



    /*============================================================================================================*/


    /*MÉTODOS DE OBTENÇÃO DE INFORMAÇÕES DO CENÁRIO*/
    double getLastUpdateTime();
    Matriz4d getBallTransform();
    Matriz4d getAgentTransform();
    Coordenada3d getHeadAgentPosition();
    Coordenada3d getAgentPosition();

    Matriz4d* readTransformationMatrix(ParserTrainer* sexpression);


    /*MÉTODOS PARA OS EXPERIMENTOS*/
    void aborteTeste();
    void run();
    void initParametros();
    void setIncQueda();
    int	getQtdQuedas();
    bool isWithinArea2(Coordenada3d point1,Coordenada3d point2);//ver se point1 esta na area point2

    /*Metodos para o Trainer*/
    void	setDistancia(int);
    void	setAnguloAgenteBola(double);
    void	setTipo(int);
    void 	setPosicaoXAgente(double);
    void	setSomaTempo(double tempo);
    double	getSomaTempo();
    void	setTempoInicial(double tempo);
    double	getTempoInicial();
    void	setTempoFinal(double tempo);
    double	getTempoFinal();
    double 	calcVelocity();
    double 	getQuedasPorDistancia();
    double 	calcMediaTempoQuedas();
    void	setTempoMaximoCaido(double tempo);
    double	getTempoMaximoCaido();
    void	setTempoMaximo(double);
    void    setRaioLimi(double);
    Coordenada3d posicaoBolaAngulo(double angulo);
//    void setAgentPositionAndDirection(int unum, PlaySide teamSide,Vector3d newPosition, double newDirection);
//    void setBatteryLevel(int unum, PlaySide teamSide, double batteryLevel);
//    void setTemperature(int unum, PlaySide teamSide, double temperature);
//    void setBallPositionAndVelocity(Vector3d newPosition, Vector3d newVelocity);

    //TODO:Experimentos
    void initExperimentoUm();
    void initExperimentoDois();
    void initExperimentoTres();
	void ExperimentoUm();
	void ExperimentoTres();
	void imprimeEstatistica();

	static std::string retornaMensage();









private:

	double 			mLastUpdateTime;
	Matriz4d 		mBallTransform;
	Matriz4d 		mAgentTransform;
	Matriz4d		mAgentTransformHead;


  /*=================  Atributos novos ===============================================================*/
	/*parte do robo temp nao será usando*/
	//Matriz4d		mAgentTransformupperarm ;
	/*parte do robo temp não será usado*/
	//Matriz4d		mAgentTransforlowerarm ;
	 std::string    getMensageM ;//criado para ver toda mensagem
     Agente         agente3dV[23];//vetores dea agentes
     Agente         agente3d; //agente modelo
     int            contAgente;//variavel para contabilizar quantidade de agente no campo
     int            lacoTeste, contMengCompl,contaMensParcial,contaMensCortada;//variável para parar o laco de execucao
     int            conAgR;
     int            lim;
     std::string    listEstJogo;
     std::string    sScoreLeft;
     std::string    sScoreRigth;
     std::string    sPlayMode;
     std::string    timpoMensage;//variavel para teste e de arquivos
     std::string    log_end;

     Estatisticas   estat;
     char timeStr [9];//atributo para pegar data
 	 std::ofstream graCoor;//atribuito para manupilação de arquivos coordenadas;


   /*============================================================================================================*/



	ConexaoTCP* 	mConnection;
	ParserTrainer 	mParser;

	std::string mensagem; //criado para teste com mensagem estatica
	double mPosicaoXAgente;
	double mMediaTempoQuedas;
	double mQuedasPorDistancia;
	double mVelocidadeMedia;

	double limitRaio;
//	void update(std::string content);
//	Matrix4d* readTransformationMatrix(ParserTrainer* sexpression);


	int mContQuedas;
	double mAnguloAgenteBola;
	double mTempo1;//TempoInicial : tempo inicial para os intervalos de tempos entre quedas
	double mTempo2;//TempoFinal : tempo em que o agente caiu
	double mSomaTempo;//SomaTempo :  soma dos intervalos dos tempos entre quedas
	double mDistancia;//Distância entre o agente e a bola
	double mDistanciaInicial;
	double mCont;//mCont para evitar o erro de duplicação no log e erro de sincronização
	double mTempoMaximo;//Tempo máximo para chegar a bola
	bool mCaido,flagPog,fim1,fim2,fim3;
	bool mChegou, starInicial;


	//TODO: Qual experimento vai ser executado
	int mTipo;
};

#endif
